using System.Diagnostics;
using System;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using Devv.Core.Erroo;
using Devv.Core.Utils;
using ILMerging;


namespace ILMergeGUI
{
	public partial class MainForm
	{
		public MainForm()
		{
			InitializeComponent();
			
			//Added to support default instance behavour in C#
			if (defaultInstance == null)
				defaultInstance = this;
		}
		
		#region Default Instance
		
		private static MainForm defaultInstance;
		
		/// <summary>
		/// Added by the VB.Net to C# Converter to support default instance behavour in C#
		/// </summary>
		public static MainForm Default
		{
			get
			{
				if (defaultInstance == null)
				{
					defaultInstance = new MainForm();
					defaultInstance.FormClosed += new FormClosedEventHandler(defaultInstance_FormClosed);
				}
				
				return defaultInstance;
			}
		}
		
		static void defaultInstance_FormClosed(object sender, FormClosedEventArgs e)
		{
			defaultInstance = null;
		}
		
		#endregion
		
		#region Main methods
		
		public void MainForm_Load(System.Object sender, System.EventArgs e)
		{
			
			if (Settings.Default.FirstRun)
			{
				Settings.Default.Upgrade();
				Settings.Default.FirstRun = false;
			}
			
			Text += " " + AssemblyInfo.GetFriendlyVersion(Assembly.GetExecutingAssembly());
			
			ChkCopyAttributes.Checked = Settings.Default.CopyAttributes;
			ChkUnionDuplicates.Checked = Settings.Default.UnionDuplicates;
			CboTargetFramework.SelectedIndex = Settings.Default.FrameworkIndex;
			
			if (Settings.Default.Debug)
			{
				CboDebug.SelectedIndex = 1;
			}
			else
			{
				CboDebug.SelectedIndex = 0;
			}
			
			if (! string.IsNullOrEmpty(Settings.Default.LastFolder))
			{
				OpenFile.InitialDirectory = Settings.Default.LastFolder;
			}
			
		}
		
		public void MainForm_HelpRequested(System.Object sender, HelpEventArgs hlpevent)
		{
			
			Process.Start("http://www.vivasky.com/");
			hlpevent.Handled = true;
			
		}
		
		public void OpenFile_FileOk(System.Object sender, System.ComponentModel.CancelEventArgs e)
		{
			
			Settings.Default.LastFolder = Path.GetDirectoryName(OpenFile.FileName);
			
		}
		
		#endregion
		
		#region Add assembiles
		
		public void ButAddFile_Click(System.Object sender, System.EventArgs e)
		{
			
			string[] arrFiles;
			bool blnDuplicate;
			string strExtension;
			int i;
			int z;
			
			OpenFile.CheckFileExists = true;
			OpenFile.Multiselect = true;
			OpenFile.FileName = string.Empty;
			OpenFile.Filter = ".NET Assembly|*.dll;*.exe";
			
			if (OpenFile.ShowDialog() == DialogResult.OK)
			{
				
				ButMerge.Enabled = true;
				
				arrFiles = OpenFile.FileNames;
				
				for (i = 0; i <= arrFiles.Length - 1; i++)
				{
					
					strExtension = Path.GetExtension(arrFiles[i]).ToLower().Replace(".", "");
					
					if (strExtension != "dll" && strExtension != "exe")
					{
						continue;
					}
					
					blnDuplicate = false;
					
					for (z = 0; z <= ListAssembly.Items.Count - 1; z++)
					{
						if (arrFiles[i] == ListAssembly.Items[z].ToString())
						{
							blnDuplicate = true;
						}
					}
					
					if (! blnDuplicate)
					{
						ListAssembly.Items.Add(arrFiles[i]);
					}
					
				}
				
			}
			
		}
		
		public void ListAssembly_SelectedIndexChanged(System.Object sender, System.EventArgs e)
		{
			
			if (ListAssembly.Items.Count > 0)
			{
				ButMerge.Enabled = true;
			}
			else
			{
				ButMerge.Enabled = false;
			}
			
			if (ListAssembly.SelectedItem != null)
			{
				LblPrimaryAssembly.Text = Path.GetFileName(ListAssembly.SelectedItem.ToString());
			}
			else
			{
				LblPrimaryAssembly.Text = "...";
			}
			
		}
		
		public void ListAssembly_KeyDown(System.Object sender, KeyEventArgs e)
		{
			
			if (e.KeyCode == Keys.Delete && ListAssembly.SelectedItem != null)
			{
				ListAssembly.Items.Remove(ListAssembly.SelectedItem);
			}
			
		}
		
		#endregion
		
		#region Options
		
		public void ChkSignKeyFile_CheckedChanged(System.Object sender, System.EventArgs e)
		{
			
			ChkDelayedSign.Enabled = ChkSignKeyFile.Checked;
			TxtKeyFile.Enabled = ChkSignKeyFile.Checked;
			
		}
		
		public void ButKeyFile_Click(System.Object sender, System.EventArgs e)
		{
			
			SelectKeyFile();
			
		}
		
		public void TxtKeyFile_Leave(System.Object sender, System.EventArgs e)
		{
			
			if (! string.IsNullOrEmpty(TxtKeyFile.Text))
			{
				TxtKeyFile.Text = TxtKeyFile.Text.Trim();
			}
			
		}
		
		public void ChkGenerateLog_CheckedChanged(System.Object sender, System.EventArgs e)
		{
			
			TxtLogFile.Enabled = ChkGenerateLog.Checked;
			
		}
		
		public void ButLogFile_Click(System.Object sender, System.EventArgs e)
		{
			
			SelectLogFile();
			
		}
		
		public void TxtLogFile_Leave(System.Object sender, System.EventArgs e)
		{
			
			if (! string.IsNullOrEmpty(TxtLogFile.Text))
			{
				TxtLogFile.Text = TxtLogFile.Text.Trim();
			}
			
		}
		
		private void SelectKeyFile()
		{
			
			SetOpenFileDefaults("Strong Name Key|*.snk");
			
			if (! string.IsNullOrEmpty(TxtKeyFile.Text))
			{
				OpenFile.FileName = Path.GetFileName(TxtKeyFile.Text);
			}
			
			if (TxtKeyFile.Text.Length > 3)
			{
				OpenFile.InitialDirectory = Path.GetDirectoryName(TxtKeyFile.Text);
			}
			
			if (OpenFile.ShowDialog() == DialogResult.OK)
			{
				ChkSignKeyFile.Checked = true;
				TxtKeyFile.Text = OpenFile.FileName;
				TxtKeyFile.Focus();
			}
			
		}
		
		private void SelectLogFile()
		{
			
			SetOpenFileDefaults("Log file|*.log");
			
			if (! string.IsNullOrEmpty(TxtLogFile.Text))
			{
				OpenFile.FileName = Path.GetFileName(TxtLogFile.Text);
			}
			
			if (TxtLogFile.Text.Length > 3)
			{
				OpenFile.InitialDirectory = Path.GetDirectoryName(TxtLogFile.Text);
			}
			
			if (OpenFile.ShowDialog() == DialogResult.OK)
			{
				ChkGenerateLog.Checked = true;
				TxtLogFile.Text = OpenFile.FileName;
				TxtLogFile.Focus();
			}
			
		}
		
		#endregion
		
		#region Output
		
		public void ButOutputPath_Click(System.Object sender, System.EventArgs e)
		{
			
			SelectOutputPath();
			
		}
		
		public void TxtOutputPath_TextChanged(System.Object sender, System.EventArgs e)
		{
			
			if (! string.IsNullOrEmpty(TxtOutputPath.Text))
			{
				TxtOutputPath.Text = TxtOutputPath.Text.Trim();
			}
			
		}
		
		private void SelectOutputPath()
		{
			
			SetOpenFileDefaults("Assembly|*.dll;*.exe");
			
			if (ListAssembly.SelectedItem != null)
			{
				OpenFile.DefaultExt = Path.GetExtension(ListAssembly.SelectedItem.ToString());
			}
			
			if (! string.IsNullOrEmpty(TxtOutputPath.Text.Trim()))
			{
				OpenFile.FileName = Path.GetFileName(TxtOutputPath.Text);
			}
			
			if (TxtOutputPath.Text.Length > 3)
			{
				OpenFile.InitialDirectory = Path.GetDirectoryName(TxtOutputPath.Text);
			}
			
			if (OpenFile.ShowDialog() == DialogResult.OK)
			{
				TxtOutputPath.Text = OpenFile.FileName;
				TxtOutputPath.Focus();
			}
			
		}
		
		#endregion
		
		#region Merge
		
		public void ButMerge_Click(System.Object sender, System.EventArgs e)
		{
			
			ILMerge objILMerge = new ILMerge();
			FileInfo objFile;
			string[] arrAssemblies = new string[ListAssembly.Items.Count - 1 + 1];
			int i = 0;
			int a = 1;
			
			PreMerge();
			
			if (! Devv.Core.Utils.IO.ValidatePath(TxtOutputPath.Text))
			{
                MessageBox.Show(Labels.Error_NoOutputPath, Labels.ErrorTerm, MessageBoxButtons.OK, MessageBoxIcon.Error);
				TxtOutputPath.Focus();
				return;
			}
			else
			{
				TxtOutputPath.Text = TxtOutputPath.Text.Trim();
			}
			
			if (Devv.Core.Utils.IO.ValidatePath(TxtKeyFile.Text) && ! File.Exists(TxtKeyFile.Text))
			{
                MessageBox.Show(Labels.Error_KeyFileNotExists, Labels.ErrorTerm, MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			
			if (File.Exists(TxtOutputPath.Text))
			{
				
				try
				{
					objFile = new FileInfo(TxtOutputPath.Text);
					objFile.Attributes = FileAttributes.Normal;
					objFile.Delete();
					objFile = null;
				}
				catch
				{
                    MessageBox.Show(Labels.Error_OutputPathInUse, Labels.ErrorTerm, MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}
				
			}
			
			if (ListAssembly.SelectedItem == null)
			{
				for (i = 0; i <= ListAssembly.Items.Count - 1; i++)
				{
					if (Path.GetExtension(ListAssembly.Items[i].ToString()).ToLower() == ".exe")
					{
						ListAssembly.SelectedIndex = i;
						i = ListAssembly.Items.Count;
					}
				}
			}
			
			if (ListAssembly.SelectedItem == null)
			{
				ListAssembly.SelectedIndex = 0;
			}
			
			arrAssemblies[0] = ListAssembly.SelectedItem.ToString();
			
			for (i = 0; i <= ListAssembly.Items.Count - 1; i++)
			{
				
				if (TxtOutputPath.Text == ListAssembly.Items[i].ToString())
				{
					
					i = ListAssembly.Items.Count;

                    MessageBox.Show(Labels.Error_OutputConflict, Labels.ErrorTerm, MessageBoxButtons.OK, MessageBoxIcon.Error);
					TxtOutputPath.Focus();
					
					return;
					
				}
				else if (i != ListAssembly.SelectedIndex)
				{
					
					arrAssemblies[a] = ListAssembly.Items[i].ToString();
					a++;
					
				}
				
			}
			
			objILMerge.CopyAttributes = ChkCopyAttributes.Checked;
			objILMerge.UnionMerge = ChkUnionDuplicates.Checked;
			
			if (ChkSignKeyFile.Checked)
			{
				objILMerge.KeyFile = TxtKeyFile.Text;
				objILMerge.DelaySign = ChkDelayedSign.Checked;
			}
			
			switch (CboDebug.SelectedIndex)
			{
				case 0:
					objILMerge.DebugInfo = true;
					break;
				case 1:
					objILMerge.DebugInfo = false;
					break;
			}
			
			switch (CboTargetFramework.SelectedIndex)
			{
				case 0:
                    objILMerge.SetTargetPlatform("4.0", "C:\\WINDOWS\\Microsoft.NET\\Framework\\v4.0");
					break;
				case 1:
                    objILMerge.SetTargetPlatform("2.0", "C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727");
					break;
				case 2:
                    objILMerge.SetTargetPlatform("1.1", "C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322");
					break;
                case 3:
                    objILMerge.SetTargetPlatform("1.0", "C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.0.3705");
                    break;
			}
			
			objILMerge.TargetKind = ILMerge.Kind.SameAsPrimaryAssembly;
			objILMerge.OutputFile = TxtOutputPath.Text;
			objILMerge.SetInputAssemblies(arrAssemblies);
			
			Cursor = Cursors.WaitCursor;
			EnableForm(false);
			
			WorkerILMerge.RunWorkerAsync(objILMerge);
			
		}
		
		public void WorkerILMerge_DoWork(System.Object sender, System.ComponentModel.DoWorkEventArgs e)
		{
			
			try
			{
				((ILMerge) e.Argument).Merge();
				e.Result = null;
			}
			catch (Exception ex)
			{
				e.Result = ex;
			}
			
		}
		
		public void WorkerILMerge_RunWorkerCompleted(System.Object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
		{
			
			FileInfo objFile = new FileInfo(TxtOutputPath.Text);
			
			Cursor = Cursors.Default;
			EnableForm(true);
			
			if (e.Error != null)
			{
				ErrorHandler.Handle(e.Error);
			}
			
			if (e.Result != null)
			{
                MessageBox.Show(Labels.Error_MergeException + Environment.NewLine + ((Exception)e.Result).Message, Labels.ErrorTerm, MessageBoxButtons.OK, MessageBoxIcon.Warning);
			}
			else if (! objFile.Exists || objFile.Length < 4096)
			{
                MessageBox.Show(Labels.Error_CantMerge, Labels.ErrorTerm, MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			else
			{
                MessageBox.Show(Labels.AssembliesMerged,Labels.Done, MessageBoxButtons.OK, MessageBoxIcon.Information);
			}
			
		}
		
		private void PreMerge()
		{
			
			if (string.IsNullOrEmpty(TxtKeyFile.Text))
			{
				ChkSignKeyFile.Checked = false;
			}
			
			if (string.IsNullOrEmpty(TxtLogFile.Text))
			{
				ChkGenerateLog.Checked = false;
			}
			
			if (TxtOutputPath.Text.Length < 5)
			{
				SelectOutputPath();
			}
			
		}
		
		private void EnableForm(bool Enable)
		{
			
			ListAssembly.Enabled = Enable;
			ButAddFile.Enabled = Enable;
			BoxOptions.Enabled = Enable;
			BoxOutput.Enabled = Enable;
			ButMerge.Enabled = Enable;
			ImgLoading.Visible = ! Enable;
			ImgLoading.Enabled = ! Enable;
			
			Application.DoEvents();
			
		}
		
		#endregion
		
		#region Links
		
		public void ImgDonate_Click(System.Object sender, System.EventArgs e)
		{
			
			Process.Start("http://devv.com/Donate.aspx?ILMerge-GUI");
			
		}
		
		public void LinkHomepage_LinkClicked(System.Object sender, LinkLabelLinkClickedEventArgs e)
		{
			
			Process.Start(LinkHomepage.Text);
			
		}
		
		public void LinkILMerge_LinkClicked(System.Object sender, LinkLabelLinkClickedEventArgs e)
		{
			
			Process.Start(LinkILMerge.Text);
			
		}
		
		#endregion
		
		#region Helper methods
		
		private void SetOpenFileDefaults(string filter)
		{
			
			OpenFile.CheckFileExists = false;
			OpenFile.Multiselect = false;
			OpenFile.Filter = filter;
			
		}
		
		#endregion
		
	}
}
